Reactive
响应式编程
基于事件驱动(事件模式,或者订阅者模式),类似于Netty异步事件编程模型.
对不同的事件做不同的处理.所有信息都通过一个编程模型处理.
好处
传统模型相比
- JavaWeb开发,基于Servlet. Servlet3.0之前 线程阻塞模型,只有当业务处理完成并返回后时结束Servlet线程.
- 3.0规范新特性,支持异步处理-Servlet线程将耗时操作委派给另一个线程完成.在不生成响应的情况下返回至容器.(问题)
Guava的EventBus实现
订阅者模式,观察者模式
1 | public class EventBusDemo { |
Mono和Flux常用API
都是数据反应式编程的核心组件.
Reactor是JVM的完全非阻塞响应式编程基础,具有高效的需求管理(以管理”背压”的形式)
它直接与Java 8功能的API,特别是整合CompletableFuture,Stream和 Duration
Flux 相当于一个 RxJava Observable 观察者
WebFlux
Spring WebFlux是随Spring 5推出的响应式Web框架。
Spring WebFlux快速上手——响应式Spring的道法术器
微服务,部署包大小,应用占用内存大小.
Rsocket
用于响应式应用程序的新网络协议(应用层协议).
提供Java,JavaScript,C ++和Kotlin等实现
它是一种基于Reactive Streams背压的双向,多路复用,基于消息的二进制协议
语言无关.
目的
该协议专门设计用于与Reactive风格应用配合使用,这些应用程序基本上是非阻塞的,并且通常(但不总是)与异步行为配对
所谓Reactive背压: 即发布者无法向订户发送数据直到该订户已经准备就绪的想法,这是与“异步”的关键区别。(服务端主动)
问题: 很多个客户端对于同一个消息,准备好的时间层次不一,服务端怎么控制这个(这个消息需要一直保存着吗,什么时候清理).
反应式编程(响应式reactive)是 Java 中高效应用的下一个前沿。但有两个主要障碍 -数据访问和网络。RSocket旨在解决后一个问题,而R2DBC旨在解决前者问题。
iPhone和Andriod手机,与后端服务交互,提供数据统计,所有这些互动模型,http并不是为此设计.
http. 超文本传输协议,用于从WWW服务器传输超文本到本地浏览器的传输协议。它可以使浏览器更加高效,使网络传输减少.
rest. 基于HTTP的REST服务. restTemplate. 获取http资源, 通过指定的一些格式(json等).
- 数据统计收集
- 消息推送
- 异步响应
RSocket、. Envoy和. Istio
从微服务治理的角度看RSocket、. Envoy和. Istio
重点是把反应流的实现,提升到应用层上来。
其实在底层的协议中,就有反应流的实现,tcp的滑动窗口就是很好的例子。
很大一部分的线上故障是由于阻塞链接造成的.
简单的例子是如果所有的通讯都是反应式的,那就不用容断了.
与http不同的四种交互模式 (重点)
Fire-and-Forget
优化请求/响应,在不需要响应时非常有用,例如非关键事件日志记录。请求/响应
当您发送一个请求并收到一个响应时,就像HTTP一样。即使在这里,该协议也具有优于HTTP的优点,因为它是异步和多路复用的。请求/流
类似于返回集合的请求/响应,集合被回送而不是查询直到完成,因此例如发送银行帐号,用实时的帐户事务流进行响应。频道
允许任意交互模型的双向消息流。
Unix网络编程模型中,底层操作系统的通道都是全双工的,同时支持读写操作.
多路复用的Selector不短的轮询注册在其上的Channel.如果某个Channel上面发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来.然后通过SelectionKey可以获取就绪的Channel的集合,进行后续的I/O操作.
TomcatNio 针对网络IO层面的异步-多路复用.(读写)
Rsocket是交互模式的异步.(或者说Rsocket的请求和响应与Http的请求和响应有什么区别,优点在那里.)
Http的异步通过callBack回调实现.(比如短信交互流程)
客户端使用http发送,短信平台和网关再到运营商都是长链接协议.短信平台受到同一链路上的送达之后.会callBack客户端.客户端收到后,处理回调.如果回调资源处理不当(处理不过来),会导致回调消息丢失. (Rsocket回压场景)
这种http的异步是通过应用程序多次请求实现.再就是客户端层面控制异步. 将请求后的等待丢进线程池或者队列来存储 AsyncCall,然后去做其他的事情.
将 AsycnCall 添加到队列中。将任务交给 Dispatcher 去执行。
比如 OKHTTP实现的异步请求.
- 使用线程池处理异步任务(这种开销太大,很少做).真正的异步执行者 AsyncCall
- 使用队列.将 AsycnCall 添加到队列中。将任务交给 Dispatcher 去执行
在使用 Dispatcher 会将 AsyncCall 交给指定的线程去执行,而 AsyncCall 是 NamedRunnable 的子类
Rsocket的异步,理解为没有收到响应,链接保持,但可以做其他事情,受到响应后再做处理.Rsocket天然支持?